package com.nameAir.vo
{
	import com.nameAir.events.EpisodeSearchResultEvent;
	import com.nameAir.events.EpisodeSearchStartEvent;
	import com.nameAir.events.SeriesSearchResultEvent;
	import com.nameAir.events.SeriesSearchStartEvent;
	
	import flash.events.EventDispatcher;
	import flash.filesystem.File;
	
	import mx.collections.ArrayCollection;
	import mx.utils.StringUtil;
	
	import theTVDB.TheTVDB;
	import theTVDB.com.vo.EpisodeVO;
	import theTVDB.com.vo.SeriesSearchVO;
	import theTVDB.com.vo.SeriesVO;

	[Bindable]
	public class MediaFile extends EventDispatcher
	{
		protected var tvdb:TheTVDB = TheTVDB.getInstance();

		protected var _baseFile:File;
		protected var _season:int;
		protected var _episode:int;
		protected var _manualShowTitle:String;
		protected var _matchedSeriesTitle:String;
		protected var _episodeName:String;

		protected var _selectedShowID:String;

		protected var _searching:Boolean = false;
		protected var _pendingSearch:Boolean = false;
		protected var _searchResults:ArrayCollection;

		protected var _gettingSeries:Boolean = false;
		protected var _tvdbSeries:SeriesVO;

		protected var _gettingEpisode:Boolean = false;
		protected var _pendingEpisodeSearch:Boolean = false;
		protected var _tvdbEpisode:EpisodeVO;
		
		protected var _holdLookup:Boolean = false;

		public static const SeasonEpisodeRegExArray:Array = new Array(
							"\\[[Ss(Se)]([0-9]+)\\]_\\[[Ee(Ep)]([0-9]+)([^\\\\/]*)"
							,"[\\._ \\-]+[Ss(Se)]+([0-9]+)[x\\.\\-]?[Ee(Ep)]+([0-9]+)([^\\\\/]*)"
							,"[\\._ \\-]+([0-9]+)x([0-9]+)([^\\\\/]*)"
							,"[\\._ \\-]+([0-9]+)([0-9][0-9])([\\._ \\-][^\\\\/]*)"
							,"Season[\\._ ]+([0-9]+)[\\\\/]([0-9]+)[^\\\\/]*"
							,"[\\\\/]s([0-9]+)e([0-9]+)"
							,"Season[ ._-]*([0-9]+)[ ._-]*Episode[ ._-]*([0-9]+)[^\\\\/]*"
							,"Season[ ._-]*([0-9]+)[\\\\\/]Episode[ ._-]*([0-9]+)"
							)

		public function MediaFile()
		{
		}

		public function get searching():Boolean
		{
			return _searching;
		}

		public function get gettingSeries():Boolean
		{
			return _gettingSeries;
		}

		public function get gettingEpisode():Boolean
		{
			return _gettingEpisode;
		}

		public function get matchedSeriesName():String
		{
			return _matchedSeriesTitle;
		}

		public function get matchedEpisode():EpisodeVO
		{
			return _tvdbEpisode;
		}

		public function get file():File
		{
			return _baseFile;
		}

		public function set file(file:File):void
		{
			_baseFile = file;

			var regex:RegExp;

			var fileName:String = _baseFile.name;

			for each (var exp:String in SeasonEpisodeRegExArray)
			{
				regex = new RegExp(exp);
				var result:Object = regex.exec(fileName);
				if (result && result is Array)
				{
					_manualShowTitle = StringUtil.trim(fileName.substr(0,result.index).replace("."," ").replace("_"," "));
					_season = result[1];
					_episode = result[2];
					return;
				}

				result = regex.exec(_baseFile.nativePath);
				if (result && result is Array)
				{
					var tempShowName:String = StringUtil.trim(_baseFile.nativePath.substr(0,result.index).replace("."," ").replace("_"," "));
					var nameArray:Array = tempShowName.split(File.separator);
					_manualShowTitle = nameArray[nameArray.length - 2];
					_season = result[1];
					_episode = result[2];
					return;
				}
			}
		}

		public function get fileName():String
		{
			return _baseFile.name;
		}

		public function get fileFullName():String
		{
			return _baseFile.nativePath;
		}

		public function get season():int
		{
			return _season;
		}

		public function set season(value:int):void
		{
			_season = value;
			getEpisodeData();
		}
		public function get episode():int
		{
			return _episode;
		}

		public function set episode(value:int):void
		{
			_episode = value;
			getEpisodeData();
		}

		public function get manualShowTitle():String
		{
			return _manualShowTitle;
		}

		public function set manualShowTitle(value:String):void
		{
			_manualShowTitle = value;
		}

		public function get episodeName():String
		{
			return _episodeName;
		}

		public function set episodeName(value:String):void
		{
			_episodeName = value;
		}

		public function get searchResult():ArrayCollection
		{
			return _searchResults;
		}

		public function set seriesID(id:String):void
		{
			if (_tvdbSeries && id == _tvdbSeries.id)
				return;
			_tvdbSeries = null;
			_selectedShowID = id;
			_gettingSeries = true;
			getEpisodeData();
			tvdb.getSeriesData(id,tvdbSeriesResult);

		}

		public function get seriesID():String
		{
			return _selectedShowID;
		}

		public function tvdbSeriesResult(data:SeriesVO):void
		{
			_gettingSeries = false;
			_tvdbSeries = data;
			if (_tvdbSeries)
			{
				_matchedSeriesTitle = _tvdbSeries.seriesName;
				
			}
		}

		public function searchTVDB():void
		{

			if (_searching)
			{
				_pendingSearch = true;
			}
			else
			{
				if (!_pendingSearch)
					dispatchEvent(new SeriesSearchStartEvent());

				_searching = true;
				tvdb.searchForSeries(_manualShowTitle,tvdbResults);
			}

		}

		protected function tvdbResults(data:ArrayCollection):void
		{
			_searching = false;
			if (_pendingSearch)
			{
				searchTVDB();
				_pendingSearch = false;
				return;
			}
			_searchResults = data;
			if (_searchResults && _searchResults.length > 0)
			{
				_matchedSeriesTitle = (_searchResults.getItemAt(0) as SeriesSearchVO).seriesName;
				getEpisodeData();
			}
			dispatchEvent(new SeriesSearchResultEvent());
		}

		public function getEpisodeData():void
		{
			var id:String;
			if (_tvdbSeries)
			{
				id = _tvdbSeries.id;
			}
			if (_selectedShowID)
			{
				id = _selectedShowID;
			}
			else if (_searchResults && _searchResults.length > 0)
			{
				id = (_searchResults.getItemAt(0) as SeriesSearchVO).id;
			}
			if (id)
			{

				if (_gettingEpisode)
				{
					_pendingEpisodeSearch = true;
				}
				else
				{
					if (!_pendingEpisodeSearch)
						dispatchEvent(new EpisodeSearchStartEvent());

					_tvdbEpisode = null;
					_gettingEpisode = true;
					tvdb.getDefaultEpisodeData(id, _season, _episode, episodeDataResults);

				}

			}
		}

		protected function episodeDataResults(data:EpisodeVO):void
		{
			_gettingEpisode = false;
			if (_pendingEpisodeSearch)
			{
				getEpisodeData();
				_pendingEpisodeSearch = false;
				return;
			}

			_tvdbEpisode = data;
			if (_tvdbEpisode)
				_episodeName = _tvdbEpisode.EpisodeName;
			else
				_episodeName = ""
			dispatchEvent(new EpisodeSearchResultEvent());
		}
	}
}
